package top.goldenyear.porpoise.infra.storage.service;

import cn.hutool.v7.core.convert.ConvertUtil;
import com.easy.query.api.proxy.client.EasyEntityQuery;
import java.util.List;

import com.easy.query.solon.annotation.Db;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Init;
import org.noear.solon.data.annotation.Ds;
import top.goldenyear.porpoise.common.core.exception.ErrorCode;
import top.goldenyear.porpoise.common.core.exception.ServiceException;
import top.goldenyear.porpoise.common.core.model.PlainOption;
import top.goldenyear.porpoise.framework.web.core.model.PageResult;
import top.goldenyear.porpoise.framework.web.core.model.query.QPage;
import top.goldenyear.porpoise.framework.web.core.service.BaseService;
import top.goldenyear.porpoise.infra.storage.config.FileConfig;
import top.goldenyear.porpoise.infra.storage.core.util.FileClientUtils;
import top.goldenyear.porpoise.infra.storage.dto.StorageConfigDto;
import top.goldenyear.porpoise.infra.storage.model.StorageConfig;
import top.goldenyear.porpoise.infra.storage.model.proxy.StorageConfigProxy;

/**
 * 文件配置表 Service 服务层
 *
 * @author airhead
 * @since 2025-04-20
 */
@Component
@Slf4j
public class StorageConfigService extends BaseService<StorageConfig, StorageConfigProxy> {
  @Db
  private EasyEntityQuery easyEntityQuery;

  public StorageConfigService() {
    super(StorageConfig.class, StorageConfigProxy.class);
  }

  public Boolean createStorageConfig(StorageConfigDto storageConfigDto) {
    StorageConfig storageConfig = StorageConfigDto.convert(storageConfigDto);
    return createStorageConfig(storageConfig);
  }

  public Boolean createStorageConfig(StorageConfig storageConfig) {
    boolean save = save(storageConfig);
    if (save) {
      setOtherToSlaver(storageConfig);
    }
    init(storageConfig);

    return save;
  }

  public Boolean updateStorageConfig(StorageConfigDto storageConfigDto) {
    StorageConfig storageConfig = StorageConfigDto.convert(storageConfigDto);
    return updateStorageConfig(storageConfig);
  }

  public Boolean updateStorageConfig(StorageConfig storageConfig) {
    boolean update = updateById(storageConfig);
    if (update) {
      setOtherToSlaver(storageConfig);
    }

    init(storageConfig);

    return update;
  }

  public StorageConfig getStorageConfig(Integer id) {
    return getById(id);
  }

  public Boolean deleteStorageConfig(Integer id) {
    if (getById(id) == null) {
      throw new ServiceException(ErrorCode.builder().msg("记录不存在").build());
    }

    return deleteById(id);
  }

  public Boolean batchDelStorageConfig(List<Integer> ids) {
    for (Integer id : ids) {
      if (getById(id) == null) {
        throw new ServiceException(ErrorCode.builder().msg("记录不存在").build());
      }
    }

    return deleteByIds(ids);
  }

  public List<StorageConfig> listStorageConfig(StorageConfig storageConfig) {
    return list(storageConfig);
  }

  public List<StorageConfig> simpleListStorageConfig(StorageConfig storageConfig) {
    return list(storageConfig);
  }

  public PageResult<StorageConfig> paginateStorageConfig(QPage qPage, StorageConfig storageConfig) {
    return paginate(qPage, storageConfig);
  }

  public List<PlainOption> optionsStorageConfig(StorageConfig storageConfig) {
    return listAs(storageConfig, PlainOption.class);
  }

  public StorageConfig getByIdOrMaster(Integer id) {
    if (id == null) {
      return getMaster();
    }

    StorageConfig storageConfig = getById(id);
    if (storageConfig == null) {
      return getMaster();
    }

    return storageConfig;
  }

  public StorageConfig getMaster() {
    return entityQueryable().where(configProxy -> configProxy.master().eq(true)).firstOrNull();
  }

  @Init
  public void init() {
    List<StorageConfig> storageConfigs = list();
    for (StorageConfig storageConfig : storageConfigs) {
      init(storageConfig);
    }
  }

  @Override
  protected EasyEntityQuery easyEntityQuery() {
    return easyEntityQuery;
  }

  private void setOtherToSlaver(StorageConfig storageConfig) {
    if (!Boolean.TRUE.equals(storageConfig.getMaster())) {
      return;
    }

    StorageConfig updateConfig = new StorageConfig();
    updateConfig.setMaster(false);
    entityUpdatable()
        .setColumns(storageConfigProxy -> storageConfigProxy.master().set(false))
        .where(
            storageConfigProxy -> {
              storageConfigProxy.master().eq(true);
              storageConfigProxy.id().ne(storageConfig.getId());
            })
        .executeRows();
  }

  private void init(StorageConfig storageConfig) {
    FileConfig fileConfig =
        FileConfig.of(storageConfig.getStorageType(), storageConfig.getConfig());
    FileClientUtils.add(
        ConvertUtil.toStr(storageConfig.getId()), fileConfig, storageConfig.getMaster());
  }
}
